#!/bin/bash

:<<EOF

  BASH_SOURCE[0]  和  $0 的区别
    当你需要知道当前运行脚本的确切位置而非 调用他的脚本 时，你应该使用 ${BASH_SOURCE[0]} 而不是  $0 ; 即 你不要在子脚本中使用 $0 来表示当前脚本
    $0 和 ${BASH_SOURCE[0]} 都可用于获取脚本的名称，但是它们在特定场景下提供的信息是不同的。在单个脚本中执行时，两者可能显示相同的信息。
    然而，如果你需要在函数内、被 source 的脚本中或者脚本链的任意点确定当前脚本的准确位置，${BASH_SOURCE[0]} 是更可靠的选择

  BASH_SOURCE 的本质
  实际上, BASH_SOURCE 是一个数组, 包含了当前命令或函数调用栈的脚本和源文件名的列表。
  数组中的第一个元素 ${BASH_SOURCE[0]} 是当前执行的脚本或源文件,
  第二个元素 ${BASH_SOURCE[1]} 是调用这个脚本或函数的父脚本, 以此类推。
  # echo "func3: BASH_SOURCE[0] is ${BASH_SOURCE[0]}"   #self_file
  # echo "func3: BASH_SOURCE[1] is ${BASH_SOURCE[1]}"   #parent_file
  # echo "func3: BASH_SOURCE[2] is ${BASH_SOURCE[2]}"   #grandparent_file
  # echo "func3: BASH_SOURCE[3] is ${BASH_SOURCE[3]}"   #super_grandparent_file

EOF



function func3V1()
{




  for((i = 0  ;  i < ${#BASH_SOURCE[@]}; i++))
  do
      echo "BASH_SOURCE[${i}] is  ${BASH_SOURCE[$i]} "
  done
  echo  -e  " \$0 is  $0  , but  current_script  is  ${BASH_SOURCE[0]}  "

  echo -e  "\n this is call_stack:"

  for((i = 0  ;  i < ${#FUNCNAME[@]}; i++))
  do
      echo "FUNCNAME[${i}] is  ${FUNCNAME[$i]} "
  done

    for((i = 0  ;  i < ${#BASH_LINENO[@]} -1 ; i++))
  do
      echo "BASH_LINENO[${i}] is  ${BASH_LINENO[$i]} "
  done

}


function func3V2(){

  echo  -e  " \$0 is  $0  , but  current_script  is  ${BASH_SOURCE[0]}  "

  echo -e  "\n this is call_stack:"
  for((i = 0  ;  i < ${#BASH_SOURCE[@]}; i++))
  do

      if [[ $i -eq 0  ]]; then

        echo " ${BASH_SOURCE[$i]}.${FUNCNAME[$i]} "
      else
        echo " ${BASH_SOURCE[$i]} ${FUNCNAME[$i]}:${BASH_LINENO[$((i-1))]}  "
      fi
  done





}